package com.ruoyi.utils.aly;

import cn.hutool.core.lang.Console;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.aliyun.alidns20150109.models.AddDomainRecordResponse;
import com.aliyun.alidns20150109.models.DeleteDomainRecordResponse;
import com.aliyun.alidns20150109.models.DescribeDomainRecordsResponse;
import com.aliyun.alidns20150109.models.UpdateDomainRecordResponse;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.service.ISysConfigService;

import java.util.ArrayList;
import java.util.List;

public class AlyDomainApiUtils {

    private static ISysConfigService configService = SpringUtils.getBean(ISysConfigService.class);
    /**
     * <b>description</b> :
     * <p>使用AK&amp;SK初始化账号Client</p>
     * @return Client
     *
     * @throws Exception
     */
    public static com.aliyun.alidns20150109.Client createClient() throws Exception {
        // 工程代码泄露可能会导致 AccessKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考。
        // 建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378657.html。
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.accessKeyId = configService.selectConfigByKey("aly.AccessKeyID");
        config.accessKeySecret = configService.selectConfigByKey("aly.AccessKeySecret");
        // Endpoint 请参考 https://api.aliyun.com/product/Alidns
        config.endpoint = "alidns.cn-beijing.aliyuncs.com";
        return new com.aliyun.alidns20150109.Client(config);
    }

    /**
     * 获取到域名列表
     * @return 返回数据
     */
    public static AjaxResult searchDomainList(String domain){
        try {
            List<JSONObject> domainList = new ArrayList<>();
            //得到阿里云客户端
            com.aliyun.alidns20150109.Client client = AlyDomainApiUtils.createClient();
            com.aliyun.alidns20150109.models.DescribeDomainsRequest describeDomainsRequest = new com.aliyun.alidns20150109.models.DescribeDomainsRequest();
            describeDomainsRequest.setKeyWord(domain);
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
            com.aliyun.alidns20150109.models.DescribeDomainsResponse resp = client.describeDomainsWithOptions(describeDomainsRequest, runtime);
            Console.log("========================请求域名列表响应报文========================");
            Console.log(JSONUtil.toJsonStr(resp));
            Console.log("========================请求域名列表响应报文========================");
            //处理返回报文 判断是否获取到域名数据
            if(resp.statusCode == 200){
                JSONObject resObj = JSONUtil.parseObj(resp.body);
                domainList = JSONUtil.toList(resObj.getBean("domains", JSONObject.class).getStr("domain"), JSONObject.class);
                return AjaxResult.success().put("domainList", domainList);
            }else{
                return AjaxResult.error("获取域名列表失败，未知错误，待完善错误信息！");
            }
        } catch (Exception _error) {
            return AjaxResult.error("获取域名列表失败！,失败原因："+_error.getMessage());
        }
    }

    /**
     * 通过域名和主机记录条件查询是否存在解析记录
     * @param domain 域名
     * @param rrKey 主机记录
     * @return 返回查询到的值
     */
    public static AjaxResult searchDeomainRecords(String domain, String rrKey, String type, String value){
        try {
            List<JSONObject> domainRecordsList = new ArrayList<>();
            com.aliyun.alidns20150109.Client client = AlyDomainApiUtils.createClient();
            com.aliyun.alidns20150109.models.DescribeDomainRecordsRequest describeDomainRecordsRequest = new com.aliyun.alidns20150109.models.DescribeDomainRecordsRequest();
            describeDomainRecordsRequest.setDomainName(domain);
            describeDomainRecordsRequest.setRRKeyWord(rrKey);
            describeDomainRecordsRequest.setType(type);
            describeDomainRecordsRequest.setValueKeyWord(value);
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
            // 复制代码运行请自行打印 API 的返回值
            DescribeDomainRecordsResponse resp = client.describeDomainRecordsWithOptions(describeDomainRecordsRequest, runtime);
            Console.log("========================请求域名解析记录列表响应报文========================");
            Console.log(JSONUtil.toJsonStr(resp));
            Console.log("========================请求域名解析记录列表响应报文========================");
            //处理返回报文 判断是否获取到域名数据
            if(resp.statusCode == 200){
                JSONObject resObj = JSONUtil.parseObj(resp.body);
                domainRecordsList = JSONUtil.toList(resObj.getBean("domainRecords", JSONObject.class).getStr("record"), JSONObject.class);
            }else{
                return AjaxResult.error("获取域名解析记录列表失败，未知错误，待完善错误信息！");
            }
            return AjaxResult.success().put("domainRecordsList", domainRecordsList);
        } catch (Exception _error) {
            return AjaxResult.error("获取域名解析记录列表失败,失败原因："+_error.getMessage());
        }
    }

    /**
     * 添加域名解析记录的方法
     * @param domainName 域名名称
     * @param rrKey 主机记录
     * @param type 解析记录类型
     * @param value 记录值
     * @return 返回成功与否
     */
    public static AjaxResult addDomainRecord(String domainName, String rrKey, String type, String value){
        try {
            AjaxResult aj = AlyDomainApiUtils.searchDeomainRecords(domainName, rrKey, type, "");
            if (aj.isSuccess()) {
                List<JSONObject> recordsList = JSONUtil.toList(aj.get("domainRecordsList").toString(), JSONObject.class);
                if (!(recordsList == null || recordsList.size() < 1)) {
                    JSONObject tmpJSon = recordsList.get(0);
                    //判断是否值也是一样的
                    if(!StrUtil.equals(tmpJSon.getStr("value"), value)){
                        aj = AlyDomainApiUtils.updateDomainRecord(tmpJSon.getStr("recordId"), tmpJSon.getStr("RR"), tmpJSon.getStr("type"), value);
                        if(aj.isSuccess()){
                            return aj;
                        }
                    }
                    return AjaxResult.success("记录已存在！");
                }
            }else{
                return aj;
            }
            com.aliyun.alidns20150109.Client client = AlyDomainApiUtils.createClient();
            com.aliyun.alidns20150109.models.AddDomainRecordRequest addDomainRecordRequest = new com.aliyun.alidns20150109.models.AddDomainRecordRequest();
            //赋值参数
            addDomainRecordRequest.setDomainName(domainName);
            addDomainRecordRequest.setRR(rrKey);
            addDomainRecordRequest.setType(type);
            addDomainRecordRequest.setValue(value);
            //其他配置
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
            // 复制代码运行请自行打印 API 的返回值
            AddDomainRecordResponse resp = client.addDomainRecordWithOptions(addDomainRecordRequest, runtime);
            Console.log("========================添加域名解析记录列表响应报文========================");
            Console.log(JSONUtil.toJsonStr(resp));
            Console.log("========================添加域名解析记录列表响应报文========================");
            //处理返回报文 判断是否获取到域名数据
            if(resp.statusCode == 200){
                JSONObject resObj = JSONUtil.parseObj(resp.body);
                return AjaxResult.success("", resObj.getStr("RecordId"));
            }else{
                return AjaxResult.error("添加域名解析记录失败，未知错误，待完善错误信息！");
            }
        } catch (Exception _error) {
            _error.printStackTrace();
            return AjaxResult.error("添加域名解析记录失败！,失败原因："+_error.getMessage());
        }
    }

    /**
     * 修改域名解析记录的方法
     * @param recordId 域名名称
     * @param rrKey 主机记录
     * @param type 解析记录类型
     * @param value 记录值
     * @return 返回成功与否
     */
    public static AjaxResult updateDomainRecord(String recordId, String rrKey, String type, String value){
        try {
            com.aliyun.alidns20150109.Client client = AlyDomainApiUtils.createClient();
            com.aliyun.alidns20150109.models.UpdateDomainRecordRequest updateDomainRecordRequest = new com.aliyun.alidns20150109.models.UpdateDomainRecordRequest();
            //赋值参数
            updateDomainRecordRequest.setRecordId(recordId);
            updateDomainRecordRequest.setRR(rrKey);
            updateDomainRecordRequest.setType(type);
            updateDomainRecordRequest.setValue(value);
            //其他配置
            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
            // 复制代码运行请自行打印 API 的返回值
            UpdateDomainRecordResponse resp = client.updateDomainRecordWithOptions(updateDomainRecordRequest, runtime);
            Console.log("========================修改域名解析记录列表响应报文========================");
            Console.log(JSONUtil.toJsonStr(resp));
            Console.log("========================修改域名解析记录列表响应报文========================");
            //处理返回报文 判断是否获取到域名数据
            if(resp.statusCode == 200){
                JSONObject resObj = JSONUtil.parseObj(resp.body);
                return AjaxResult.success("修改成功！", resObj.getStr("RecordId"));
            }else{
                return AjaxResult.error("修改域名解析记录失败，未知错误，待完善错误信息！");
            }
        } catch (Exception _error) {
            _error.printStackTrace();
            return AjaxResult.error("修改域名解析记录失败！,失败原因："+_error.getMessage());
        }
    }

    /**
     * 删除域名解析记录的方法
     * @param domainName 域名名称
     * @param rrKey 主机记录
     * @param type 解析记录类型
     * @param value 记录值
     * @return 返回成功与否
     */
    public static AjaxResult deleteDomainRecord(String domainName, String rrKey, String type, String value){
        try {
            //查询出当前操作记录
            AjaxResult aj = AlyDomainApiUtils.searchDeomainRecords(domainName, rrKey, type, value);
            //判断是否查询到值
            if(aj.isSuccess()){
                //转换数据
                List<JSONObject> recordsList = JSONUtil.toList(aj.get("domainRecordsList").toString(), JSONObject.class);
                //判断是否存在数据
                if(recordsList != null && recordsList.size() > 0){
                    //遍历每一条数据
                    for (JSONObject jsonObject : recordsList) {
                        //删除数据
                        com.aliyun.alidns20150109.Client client = AlyDomainApiUtils.createClient();
                        com.aliyun.alidns20150109.models.DeleteDomainRecordRequest deleteDomainRecordRequest = new com.aliyun.alidns20150109.models.DeleteDomainRecordRequest();
                        deleteDomainRecordRequest.setRecordId(jsonObject.getStr("recordId"));
                        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
                        // 复制代码运行请自行打印 API 的返回值
                        DeleteDomainRecordResponse resp = client.deleteDomainRecordWithOptions(deleteDomainRecordRequest, runtime);
                        Console.log("========================删除域名解析记录列表响应报文========================");
                        Console.log(JSONUtil.toJsonStr(resp));
                        Console.log("========================删除域名解析记录列表响应报文========================");
                        //处理返回报文 判断是否获取到域名数据
                        if(resp.statusCode == 200){
                            return AjaxResult.success();
                        }else{
                            return AjaxResult.error("删除域名解析记录失败，未知错误，待完善错误信息！");
                        }
                    }
                }else{
                    return AjaxResult.error("未查询到域名解析记录信息！");
                }
            }else{
                return aj;
            }
        } catch (Exception _error) {
            _error.printStackTrace();
            return AjaxResult.error("删除域名解析记录失败！,失败原因："+_error.getMessage());
        }
        return AjaxResult.error("未知错误！");
    }

    public static void main(String[] args) {
        AlyDomainApiUtils.searchDeomainRecords("autohttps.cn", "53loow0bn", "TXT", "");
    }
}
